/**
 * WebSocket相关组合式函数
 */
import { ref, computed, onMounted, onUnmounted, readonly } from "vue";
import { useUserStore } from "@/stores/user";
import { API_CONFIG } from "@/api/config";
import { ElMessage } from "element-plus";

type WebSocketStatus = "connecting" | "connected" | "disconnected" | "error";
type MessageHandler = (data: any) => void;

export function useWebSocket(url?: string) {
  const userStore = useUserStore();

  const socket = ref<WebSocket | null>(null);
  const status = ref<WebSocketStatus>("disconnected");
  const reconnectAttempts = ref(0);
  const maxReconnectAttempts = ref(5);
  const reconnectInterval = ref(3000);
  const heartbeatInterval = ref(30000);
  const messageHandlers = ref<Map<string, MessageHandler[]>>(new Map());

  let heartbeatTimer: NodeJS.Timeout | null = null;
  let reconnectTimer: NodeJS.Timeout | null = null;

  // 计算属性
  const isConnected = computed(() => status.value === "connected");
  const isConnecting = computed(() => status.value === "connecting");
  const isDisconnected = computed(() => status.value === "disconnected");
  const canReconnect = computed(
    () => reconnectAttempts.value < maxReconnectAttempts.value,
  );

  // 获取WebSocket URL
  const getWebSocketUrl = () => {
    if (url) return url;

    const baseUrl = API_CONFIG.WS_BASE_URL || "ws://localhost:8080";
    const token = userStore.token;

    return `${baseUrl}/ws/chat${token ? `?token=${token}` : ""}`;
  };

  // 连接WebSocket
  const connect = () => {
    if (socket.value?.readyState === WebSocket.OPEN) {
      return;
    }

    try {
      status.value = "connecting";
      socket.value = new WebSocket(getWebSocketUrl());

      socket.value.onopen = handleOpen;
      socket.value.onmessage = handleMessage;
      socket.value.onclose = handleClose;
      socket.value.onerror = handleError;
    } catch (error) {
      console.error("WebSocket连接失败:", error);
      status.value = "error";
    }
  };

  // 断开连接
  const disconnect = () => {
    if (socket.value) {
      socket.value.close(1000, "主动断开连接");
    }

    clearHeartbeat();
    clearReconnectTimer();
    status.value = "disconnected";
  };

  // 发送消息
  const send = (type: string, data?: any) => {
    if (!isConnected.value) {
      console.warn("WebSocket未连接，无法发送消息");
      return false;
    }

    try {
      const message = {
        type,
        data,
        timestamp: Date.now(),
      };

      socket.value?.send(JSON.stringify(message));
      return true;
    } catch (error) {
      console.error("发送消息失败:", error);
      return false;
    }
  };

  // 注册消息处理器
  const on = (type: string, handler: MessageHandler) => {
    if (!messageHandlers.value.has(type)) {
      messageHandlers.value.set(type, []);
    }
    messageHandlers.value.get(type)?.push(handler);
  };

  // 移除消息处理器
  const off = (type: string, handler?: MessageHandler) => {
    if (!messageHandlers.value.has(type)) {
      return;
    }

    if (handler) {
      const handlers = messageHandlers.value.get(type)!;
      const index = handlers.indexOf(handler);
      if (index > -1) {
        handlers.splice(index, 1);
      }
    } else {
      messageHandlers.value.delete(type);
    }
  };

  // 处理连接打开
  const handleOpen = () => {
    // WebSocket连接已建立
    status.value = "connected";
    reconnectAttempts.value = 0;

    // 开始心跳
    startHeartbeat();

    // 触发连接事件
    emit("connect", { timestamp: Date.now() });
  };

  // 处理消息接收
  const handleMessage = (event: MessageEvent) => {
    try {
      const message = JSON.parse(event.data);
      const { type, data } = message;

      // 处理心跳响应
      if (type === "pong") {
        return;
      }

      // 触发消息处理器
      emit(type, data);
    } catch (error) {
      // 解析消息失败，忽略错误
    }
  };

  // 处理连接关闭
  const handleClose = (event: CloseEvent) => {
    console.log("WebSocket连接已关闭:", event.code, event.reason);
    status.value = "disconnected";

    clearHeartbeat();

    // 触发断开连接事件
    emit("disconnect", {
      code: event.code,
      reason: event.reason,
      timestamp: Date.now(),
    });

    // 自动重连
    if (event.code !== 1000 && canReconnect.value) {
      scheduleReconnect();
    }
  };

  // 处理连接错误
  const handleError = (event: Event) => {
    // WebSocket连接错误
    status.value = "error";

    // 触发错误事件
    emit("error", {
      error: event,
      timestamp: Date.now(),
    });
  };

  // 触发事件
  const emit = (type: string, data: any) => {
    const handlers = messageHandlers.value.get(type);
    if (handlers) {
      handlers.forEach((handler) => {
        try {
          handler(data);
        } catch (error) {
          // 处理事件时出错，忽略错误
        }
      });
    }
  };

  // 开始心跳
  const startHeartbeat = () => {
    clearHeartbeat();

    heartbeatTimer = setInterval(() => {
      if (isConnected.value) {
        send("ping");
      }
    }, heartbeatInterval.value);
  };

  // 清除心跳
  const clearHeartbeat = () => {
    if (heartbeatTimer) {
      clearInterval(heartbeatTimer);
      heartbeatTimer = null;
    }
  };

  // 安排重连
  const scheduleReconnect = () => {
    if (!canReconnect.value) {
      ElMessage.error("WebSocket连接失败，已达到最大重连次数");
      return;
    }

    clearReconnectTimer();

    const delay = Math.min(
      reconnectInterval.value * Math.pow(2, reconnectAttempts.value),
      30000,
    );

    reconnectTimer = setTimeout(() => {
      reconnectAttempts.value++;
      console.log(
        `尝试重连WebSocket (${reconnectAttempts.value}/${maxReconnectAttempts.value})`,
      );
      connect();
    }, delay);
  };

  // 清除重连定时器
  const clearReconnectTimer = () => {
    if (reconnectTimer) {
      clearTimeout(reconnectTimer);
      reconnectTimer = null;
    }
  };

  // 重置重连计数
  const resetReconnectAttempts = () => {
    reconnectAttempts.value = 0;
  };

  // 设置重连配置
  const setReconnectConfig = (maxAttempts: number, interval: number) => {
    maxReconnectAttempts.value = maxAttempts;
    reconnectInterval.value = interval;
  };

  // 设置心跳间隔
  const setHeartbeatInterval = (interval: number) => {
    heartbeatInterval.value = interval;

    if (isConnected.value) {
      startHeartbeat();
    }
  };

  // 获取连接信息
  const getConnectionInfo = () => {
    return {
      status: status.value,
      reconnectAttempts: reconnectAttempts.value,
      maxReconnectAttempts: maxReconnectAttempts.value,
      url: getWebSocketUrl(),
      readyState: socket.value?.readyState,
    };
  };

  // 组件挂载时自动连接
  onMounted(() => {
    if (userStore.isAuthenticated) {
      connect();
    }
  });

  // 组件卸载时断开连接
  onUnmounted(() => {
    disconnect();
  });

  return {
    // 状态
    status: readonly(status),
    reconnectAttempts: readonly(reconnectAttempts),

    // 计算属性
    isConnected,
    isConnecting,
    isDisconnected,
    canReconnect,

    // 方法
    connect,
    disconnect,
    send,
    on,
    off,
    resetReconnectAttempts,
    setReconnectConfig,
    setHeartbeatInterval,
    getConnectionInfo,
  };
}

// 全局WebSocket实例
let globalWebSocket: ReturnType<typeof useWebSocket> | null = null;

export const useGlobalWebSocket = () => {
  if (!globalWebSocket) {
    globalWebSocket = useWebSocket();
  }
  return globalWebSocket;
};
